package com.zs.propertymanage.service.impl.impl;

import com.zs.propertymanage.dataObj.DTO;
import com.zs.propertymanage.dataObj.R;
import com.zs.propertymanage.dataObj.entity.Org;
import com.zs.propertymanage.mapper.OrgMapper;
import com.zs.propertymanage.service.impl.OrgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class OrgServiceImpl implements OrgService {

    @Autowired
    private OrgMapper orgMapper;

    @Override
    public R getOrg(String search, Integer currentPage, Integer pageSize) {

        List<Org> plainOrgList = orgMapper.getAllOrgWithPlain(search, (currentPage - 1) * pageSize, pageSize);      // 未经整合的组织列表

        if (search == null || search.equals("")) {      // 搜索条件为空，返回整合过的组织列表
            Map<Integer, Org> orgMap = new HashMap<>();     // 映射到哈希表，加快查询速度
            for (Org org : plainOrgList) orgMap.put(org.getId(), org);  // List 与 Map 做映射

            List<Org> resultOrgList = new ArrayList<>();    // 结果列表
            for (Org org : plainOrgList) {
                if (org.getParentId() == 0) {
                    resultOrgList.add(org);     // 先将顶层组织加入结果列表
                } else {       // 再将非顶层组织加入顶层组织的children列表
                    Org parentOrg = orgMap.get(org.getParentId());
                    List<Org> children = parentOrg.getChildren();
                    org.setParentName(parentOrg.getName());
                    children.add(org);
                    parentOrg.setChildren(children);
                }
            }
            return resultOrgList.size() > 0 ? R.ok("获取组织列表成功", new DTO<>(resultOrgList, resultOrgList.size())) : R.error("获取组织列表失败");
        } else {
            return plainOrgList.size() > 0 ? R.ok("查询组织信息成功", new DTO<>(plainOrgList, plainOrgList.size())) : R.error("未查询到组织信息");
        }

    }

    @Override
    public List<Integer> getChildrenIdList(Integer orgId) {
        List<Org> orgList = orgMapper.getAllOrgWithPlain(null, 0, 10); // 未经整合的组织列表

        Map<Integer, Integer> orgMap = new HashMap<>(); // 存放所有组织id及其父组织id
        for (Org org : orgList)
            orgMap.put(org.getId(), org.getParentId());

        Map<Integer, List<Integer>> orgChildMap = new HashMap<>();  // 存放所有组织id及其子组织id列表

        // 遍历orgMap，将数据存入orgChildMap
        for (Map.Entry<Integer, Integer> entry : orgMap.entrySet()) {
            if (!orgChildMap.containsKey(entry.getValue())) {
                orgChildMap.put(entry.getValue(), new ArrayList<>());
            }
            orgChildMap.get(entry.getValue()).add(entry.getKey());
        }

        // 2. 根据传入的组织id，获取该组织及其子组织列表
        List<Integer> resultOrgList = new ArrayList<>();    // 存放结果组织id列表
        Stack<Integer> stack = new Stack<>();   // 用于遍历组织树的栈
        if (orgId == null) orgId = 0;
        stack.push(orgId);  // 栈中放的是要遍历的顶层组织id

        while (!stack.isEmpty()) {
            int currentOrgId = stack.pop();
            resultOrgList.add(currentOrgId);
            if (orgChildMap.containsKey(currentOrgId)) {
                for (Integer childId : orgChildMap.get(currentOrgId)) {
                    stack.push(childId);
                }
            }
        }
        return resultOrgList;
    }

    @Override
    public R createOrg(Org org) {
        int result = orgMapper.createOrg(setOrgPath(org));
        return result > 0 ? R.ok("创建组织成功") : R.error("创建组织失败");
    }

    @Override
    public R updateOrg(Org org) {
        int result = orgMapper.updateOrg(setOrgPath(org));
        return result > 0 ? R.ok("更新组织成功") : R.error("更新组织失败");
    }

    /**
     * 设置组织路径
     *
     * @param org 组织
     */
    private Org setOrgPath(Org org) {
        if (org.getParentId() == 0) org.setPath(org.getName());
        else {
            Org parentOrg = orgMapper.getOrgById(org.getParentId());
            org.setPath(parentOrg.getPath() + "-" + org.getName());
        }
        return org;
    }

    @Override
    public R deleteOrg(Integer orgId) {
        int result = orgMapper.deleteOrg(orgId);
        return result > 0 ? R.ok("删除组织成功") : R.error("删除组织失败");
    }
}
